package com.happy.main.utils;

import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;

import javax.servlet.http.HttpServletRequest;
import javax.sound.midi.Soundbank;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * @program: happy-shopping-op
 * @description: 生成无状态token用于设备的登录验证是否合法
 * @author: taoxinhuan
 * @create: 2020-04-18 10:25
 **/
public class JwtUtil {
    public static final long EXPIRATION_TIME = 1_800_000L; // 半小时
    public static final String SECRET = "19960709_token_secret";
    public static final String HEADER = "token";
    public static final String USER_ID = "userId";

    public static final Integer SUPER_USER_ID=888888;
    public static final long SUPER_USER_EXPIRATION_TIME=2592_000_000L; // 有效期30天

    /**
     * 载荷内容
     * iss: jwt签发者
     * sub: jwt所面向的用户
     * aud: 接收jwt的一方
     * exp: jwt的过期时间，这个过期时间必须要大于签发时间
     * nbf: 定义在什么时间之前，该jwt都是不可用的.
     * iat: jwt的签发时间
     * jti: jwt的唯一身份标识，主要用来作为一次性token,从而回避重放攻击。
     * 来源：简书
     * 著作权归作者所有。商业转载请联系作者获得授权，非商业转载请注明出处。
     * 根据userId生成token，载荷中其他东西不申明暂时无关紧要
     * @param userId
     * @return
     */
    public static String generateToken(String userId) {
        HashMap<String, Object> map = new HashMap<>();
        map.put(USER_ID, userId);
        String jwt=null;
        if(userId==SUPER_USER_ID.toString()){
            jwt = Jwts.builder()
                    .setClaims(map)
                    .setExpiration(new Date(System.currentTimeMillis() + SUPER_USER_EXPIRATION_TIME))
                    .signWith(SignatureAlgorithm.HS512, SECRET)
                    .compact();
        }else{
            jwt = Jwts.builder()
                    .setClaims(map)
                    .setExpiration(new Date(System.currentTimeMillis() + EXPIRATION_TIME))
                    .signWith(SignatureAlgorithm.HS512, SECRET)
                    .compact();
        }
        return jwt;
    }

    /**
     * 验证token
     * @param request
     * @return 验证通过返回userId
     */
    public static Integer verifyToken(HttpServletRequest request) {
        String token = request.getHeader(HEADER);
        return verifyToken(token);
    }

    /**
     * 验证token
     * @param token
     * @return 验证通过返回userId
     */
    public static Integer verifyToken(String token) {
        if (token != null) {
            try {
                Map<String, Object> body = Jwts.parser()
                        .setSigningKey(SECRET)
                        .parseClaimsJws(token)
                        .getBody();

                for (Map.Entry entry : body.entrySet()) {
                    Object key = entry.getKey();
                    Object value = entry.getValue();
                    if (key.toString().equals(USER_ID)) {
                        return Integer.valueOf(value.toString());// userId
                    }
                }
                return null;
            } catch (Exception e) {
                throw new RuntimeException("UNAUTHORIZED");
            }
        } else {
            throw new RuntimeException("MISSING_TOKEN");
        }
    }

    public static void main(String[] args) {
        Integer userId=123456;
        String token = generateToken(userId.toString());
        System.out.println(token);
        Integer integer = verifyToken(token);
        System.out.println(integer);
    }
}
